﻿namespace Microsoft.SharePoint.Client
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Reflection;

    [ScriptType("SP.ListItem", ServerTypeId="{53cc48c0-1777-47b7-99ca-729390f06602}")]
    public class ListItem : SecurableObject
    {
        [EditorBrowsable(EditorBrowsableState.Never)]
        public ListItem(ClientRuntimeContext Context, ObjectPath ObjectPath) : base(Context, ObjectPath)
        {
        }

        [Remote]
        public virtual void DeleteObject()
        {
            ClientAction query = new ClientActionInvokeMethod(this, "DeleteObject", null);
            base.Context.AddQuery(query);
            base.RemoveFromParentCollection();
        }

        [PseudoRemote]
        internal object GetFieldValue(string fieldName)
        {
            object obj2 = null;
            if (!this.FieldValues.TryGetValue(fieldName, out obj2))
            {
                throw new PropertyOrFieldNotInitializedException();
            }
            return obj2;
        }

        internal void InitFromCreationInformation(ListItemCreationInformation creation)
        {
            if (creation != null)
            {
                base.ObjectData.Properties["FileSystemObjectType"] = creation.UnderlyingObjectType;
                base.ObjectData.Properties["Id"] = -1;
            }
        }

        protected override void InitNonPropertyFieldFromJson(string peekedName, JsonReader reader)
        {
            KeyValuePair<string, object> pair = reader.ReadKeyValue();
            this.FieldValues[pair.Key] = pair.Value;
        }

        protected override bool InitOnePropertyFromJson(string peekedName, JsonReader reader)
        {
            bool flag = base.InitOnePropertyFromJson(peekedName, reader);
            if (!flag)
            {
                switch (peekedName)
                {
                    case "ParentList":
                        flag = true;
                        reader.ReadName();
                        this.ParentList.FromJson(reader);
                        return flag;

                    case "Id":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["Id"] = reader.ReadInt32();
                        return flag;

                    case "FieldValuesAsHtml":
                        flag = true;
                        reader.ReadName();
                        this.FieldValuesAsHtml.FromJson(reader);
                        return flag;

                    case "FieldValuesAsText":
                        flag = true;
                        reader.ReadName();
                        this.FieldValuesAsText.FromJson(reader);
                        return flag;

                    case "FieldValuesForEdit":
                        flag = true;
                        reader.ReadName();
                        this.FieldValuesForEdit.FromJson(reader);
                        return flag;

                    case "DisplayName":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["DisplayName"] = reader.ReadString();
                        return flag;

                    case "File":
                        flag = true;
                        reader.ReadName();
                        this.File.FromJson(reader);
                        return flag;

                    case "FileSystemObjectType":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["FileSystemObjectType"] = reader.ReadEnum<Microsoft.SharePoint.Client.FileSystemObjectType>();
                        return flag;

                    case "EffectiveBasePermissions":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["EffectiveBasePermissions"] = reader.Read<BasePermissions>();
                        return flag;

                    case "ContentType":
                        flag = true;
                        reader.ReadName();
                        this.ContentType.FromJson(reader);
                        return flag;
                }
            }
            return flag;
        }

        protected override void LoadExpandoFields()
        {
            foreach (string str in this.FieldValues.Keys)
            {
                base.Retrieve(new string[] { str });
            }
        }

        [Remote]
        public void ParseAndSetFieldValue(string fieldName, string value_)
        {
            this.FieldValues[fieldName] = value_;
            ClientAction query = new ClientActionInvokeMethod(this, "ParseAndSetFieldValue", new object[] { fieldName, value_ });
            if (base.Context != null)
            {
                base.Context.AddQuery(query);
            }
        }

        [Remote]
        public ClientResult<Guid> Recycle()
        {
            ClientAction query = new ClientActionInvokeMethod(this, "Recycle", null);
            base.Context.AddQuery(query);
            ClientResult<Guid> result = new ClientResult<Guid>();
            base.Context.AddQueryIdAndResultObject(query.Id, result);
            base.RemoveFromParentCollection();
            return result;
        }

        public override void RefreshLoad()
        {
            base.RefreshLoad();
            this.LoadExpandoFields();
        }

        [Remote]
        internal void SetFieldValue(string fieldName, object value_)
        {
            this.FieldValues[fieldName] = value_;
            ClientAction query = new ClientActionInvokeMethod(this, "SetFieldValue", new object[] { fieldName, value_ });
            if (base.Context != null)
            {
                base.Context.AddQuery(query);
            }
        }

        [Remote]
        public virtual void Update()
        {
            ClientAction query = new ClientActionInvokeMethod(this, "Update", null);
            base.Context.AddQuery(query);
            this.RefreshLoad();
        }

        [Remote]
        public Microsoft.SharePoint.Client.ContentType ContentType
        {
            get
            {
                object obj2;
                if (base.ObjectData.ClientObjectProperties.TryGetValue("ContentType", out obj2))
                {
                    return (Microsoft.SharePoint.Client.ContentType) obj2;
                }
                Microsoft.SharePoint.Client.ContentType type = new Microsoft.SharePoint.Client.ContentType(base.Context, new ObjectPathProperty(base.Context, base.Path, "ContentType"));
                base.ObjectData.ClientObjectProperties["ContentType"] = type;
                return type;
            }
        }

        [Remote]
        public string DisplayName
        {
            get
            {
                base.CheckUninitializedProperty("DisplayName");
                return (string) base.ObjectData.Properties["DisplayName"];
            }
        }

        [Remote]
        public BasePermissions EffectiveBasePermissions
        {
            get
            {
                base.CheckUninitializedProperty("EffectiveBasePermissions");
                return (BasePermissions) base.ObjectData.Properties["EffectiveBasePermissions"];
            }
        }

        public Dictionary<string, object> FieldValues
        {
            get
            {
                Dictionary<string, object> dictionary = null;
                object obj2 = null;
                if (base.ObjectData.MethodReturnObjects.TryGetValue("$m_dict", out obj2))
                {
                    dictionary = obj2 as Dictionary<string, object>;
                }
                if (dictionary == null)
                {
                    dictionary = new Dictionary<string, object>();
                    base.ObjectData.MethodReturnObjects["$m_dict"] = dictionary;
                }
                return dictionary;
            }
        }

        [Remote]
        public FieldStringValues FieldValuesAsHtml
        {
            get
            {
                object obj2;
                if (base.ObjectData.ClientObjectProperties.TryGetValue("FieldValuesAsHtml", out obj2))
                {
                    return (FieldStringValues) obj2;
                }
                FieldStringValues values = new FieldStringValues(base.Context, new ObjectPathProperty(base.Context, base.Path, "FieldValuesAsHtml"));
                base.ObjectData.ClientObjectProperties["FieldValuesAsHtml"] = values;
                return values;
            }
        }

        [Remote]
        public FieldStringValues FieldValuesAsText
        {
            get
            {
                object obj2;
                if (base.ObjectData.ClientObjectProperties.TryGetValue("FieldValuesAsText", out obj2))
                {
                    return (FieldStringValues) obj2;
                }
                FieldStringValues values = new FieldStringValues(base.Context, new ObjectPathProperty(base.Context, base.Path, "FieldValuesAsText"));
                base.ObjectData.ClientObjectProperties["FieldValuesAsText"] = values;
                return values;
            }
        }

        [Remote]
        public FieldStringValues FieldValuesForEdit
        {
            get
            {
                object obj2;
                if (base.ObjectData.ClientObjectProperties.TryGetValue("FieldValuesForEdit", out obj2))
                {
                    return (FieldStringValues) obj2;
                }
                FieldStringValues values = new FieldStringValues(base.Context, new ObjectPathProperty(base.Context, base.Path, "FieldValuesForEdit"));
                base.ObjectData.ClientObjectProperties["FieldValuesForEdit"] = values;
                return values;
            }
        }

        [Remote]
        public Microsoft.SharePoint.Client.File File
        {
            get
            {
                object obj2;
                if (base.ObjectData.ClientObjectProperties.TryGetValue("File", out obj2))
                {
                    return (Microsoft.SharePoint.Client.File) obj2;
                }
                Microsoft.SharePoint.Client.File file = new Microsoft.SharePoint.Client.File(base.Context, new ObjectPathProperty(base.Context, base.Path, "File"));
                base.ObjectData.ClientObjectProperties["File"] = file;
                return file;
            }
        }

        [Remote]
        public Microsoft.SharePoint.Client.FileSystemObjectType FileSystemObjectType
        {
            get
            {
                base.CheckUninitializedProperty("FileSystemObjectType");
                return (Microsoft.SharePoint.Client.FileSystemObjectType) base.ObjectData.Properties["FileSystemObjectType"];
            }
        }

        [Remote]
        public int Id
        {
            get
            {
                base.CheckUninitializedProperty("Id");
                return (int) base.ObjectData.Properties["Id"];
            }
        }

        public object this[string fieldName]
        {
            [PseudoRemote(Name="GetFieldValue")]
            get
            {
                return this.GetFieldValue(fieldName);
            }
            [Remote(Name="SetFieldValue")]
            set
            {
                this.SetFieldValue(fieldName, value);
            }
        }

        [Remote]
        public List ParentList
        {
            get
            {
                object obj2;
                if (base.ObjectData.ClientObjectProperties.TryGetValue("ParentList", out obj2))
                {
                    return (List) obj2;
                }
                List list = new List(base.Context, new ObjectPathProperty(base.Context, base.Path, "ParentList"));
                base.ObjectData.ClientObjectProperties["ParentList"] = list;
                return list;
            }
        }
    }
}

